﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace ProLinq.Toolkit
{
	/// <summary>
	/// Default query implementation
	/// </summary>
	/// <typeparam name="T">Element type</typeparam>
	public class Query<T> : IOrderedQueryable<T>
	{
		#region Fields

		private readonly Expression _expression;
		private readonly QueryProvider _provider;

		#endregion

		#region Constructors

		public Query(QueryProvider provider)
		{
			if (provider == null)
			{
				throw new ArgumentNullException("provider");
			}

			_provider = provider;
			_expression = Expression.Constant(this);
		}

		public Query(QueryProvider provider, Expression expression)
		{
			if (provider == null)
			{
				throw new ArgumentNullException("provider");
			}

			if (expression == null)
			{
				throw new ArgumentNullException("expression");
			}

			_provider = provider;
			_expression = expression;
		}

		#endregion

		#region IQueryable<T>

		public IEnumerator<T> GetEnumerator()
		{
			return Provider.Execute<IEnumerable<T>>(Expression).GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		public Type ElementType
		{
			get { return typeof (T); }
		}

		public Expression Expression
		{
			get { return _expression; }
		}

		public IQueryProvider Provider
		{
			get { return _provider; }
		}

		#endregion
	}
}